package org.ricks.common.conf;

import org.ricks.utils.FileUtil;
import org.ricks.utils.StrUtil;

import javax.lang.model.type.UnknownTypeException;
import java.util.*;

/**
 * @author chenwei
 * @Title:
 * @Package
 * @Description:
 * @date 2020/8/717:15
 */
public class ConfLoader extends AbstractConfLoader {

    private static final String CUSTOM_PREFIX = "classpath: ";
    private List<org.ricks.common.conf.LoadFileName> loadFileNameList = new ArrayList<>(Arrays.asList(org.ricks.common.conf.LoadFileNameConstant.APPLICATION_PROPERTIES));
    private Map<org.ricks.common.conf.LoadFileName, Object> confMap = new TreeMap<>();
    private Map<String, Object> confValues;

    private org.ricks.common.conf.ClassHandler classHandler = org.ricks.common.conf.ClassHandler.getClassHandler();

    public void add(org.ricks.common.conf.LoadFileName loadFile) {
        loadFileNameList.add(loadFile);
    }

    public void remove(org.ricks.common.conf.LoadFileName loadFile) {
        loadFileNameList.remove(loadFile);
    }

    private ConfLoader() {
    }

    private static class ConfLoaderInner {
        private static ConfLoader confLoader = new ConfLoader();
    }

    public static ConfLoader getLoader() {
        return ConfLoaderInner.confLoader;
    }

    // 首次加载
    public void loadResult() throws Exception {
        // 前置策略，必包含前置读取自定义conf source
        Set<Class<?>> classSet = classHandler.getClassSet();
        classSet.forEach(this::loadConfSource);
        // 加载各配置源配置内容
        loadSource(confMap, loadFileNameList);
        // 合并到confValues中
        confValues = mergeSource(confMap);
    }

    // 加载自定义的配置文件
    private void loadConfSource(Class<?> clazz) {
        if (clazz.isAnnotationPresent(ConfProperties.class)) {
            ConfProperties confSource = clazz.getAnnotation(ConfProperties.class);
            // 处理自定义文件
            String fileName = confSource.value();//配置文件名/路径
            // 自定义文件名处理
            if(StrUtil.contains(fileName,CUSTOM_PREFIX)) fileName = fileName.substring(fileName.indexOf(CUSTOM_PREFIX) + CUSTOM_PREFIX.length());
            LoadSource loadSource = getLoadSource(fileName);
            org.ricks.common.conf.LoadFileName loadFile = new org.ricks.common.conf.LoadFileName(fileName, loadSource);
            if (!FileUtil.hasLoadFileName(loadFileNameList, loadFile)) {
                // 未包含则加入
                ConfLoader.getLoader().add(loadFile);
            }
            org.ricks.common.conf.ClassHandler.getClassHandler().getFixedClassMap().putIfAbsent(clazz, loadFile);
        }
    }


    private LoadSource getLoadSource(String fileName) {
        if (fileName.toLowerCase().endsWith(".properties")) {
            return org.ricks.common.conf.LoadProperties.getInstance();
        } else {
            throw new UnknownTypeException(null, "暂时不支持此种配置文件");
        }
    }

    public Map<String, Object> getSource() {
        return confValues;
    }

    public Map<org.ricks.common.conf.LoadFileName, Object> getConfMap() {
        return confMap;
    }

}
